package com.yanqu.road.server.manger.system;

import com.yanqu.road.entity.activity.fivehero.FiveHeroConfig;
import com.yanqu.road.entity.config.goods.GoodsBagInfo;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eGoodsType;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.bussiness.servercenter.CommonBussiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.travelbook.TravelBookModule;
import com.yanqu.road.server.gameplayer.module.player.CommonModule;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.TempCommonMgr;
import com.yanqu.road.server.manger.activity.fivehero.FiveHeroMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.relatives.RelativesMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;

import java.util.*;

public class CommonMgr extends TempMgr {

    private static Map<Integer, GoodsInfo> goodsInfoMap;

    private static Map<Integer, Map<Integer, List<GoodsBagInfo>>> goodsBagInfoMap;

    private static RandomHelper threadSafeRandom = new RandomHelper();

    private static List<GoodsBagInfo> clientGoodsBagInfoList;

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean reloadConfig() {
        reloadCommonData();
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    public static void reloadCommonData(){
        int channelId = 0;
        ServerInfo serverInfo = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId());
        if(null != serverInfo){
            channelId = serverInfo.getChannelId();
        }
        Map<Integer, GoodsInfo> tempGoodsInfoMap = CommonBussiness.getGoodsInfoMap();
        //新加的通过渠道来区分不同的配置，防止测试服和正式服混了，合并一起根据id替换旧的
        Map<Integer, GoodsInfo> tempGoodsInfoMapChannel = CommonBussiness.getGoodsInfoMapChannel(channelId);
        Map<Integer, GoodsInfo> mergeGoodsInfoMap = mergeGood(tempGoodsInfoMap,tempGoodsInfoMapChannel);

        TempCommonMgr.initGoodsInfoMap(mergeGoodsInfoMap);
        Map<Integer, Map<Integer, List<GoodsBagInfo>>> tempGoodsBagInfoMap = CommonBussiness.getGoodsBagInfoMap();
        Map<Integer, Map<Integer, List<GoodsBagInfo>>> tempGoodsBagInfoMapChannel = CommonBussiness.getGoodsBagInfoMapChannel(channelId);
        goodsInfoMap = mergeGoodsInfoMap;
        goodsBagInfoMap = mergeGoodBag(tempGoodsBagInfoMap,tempGoodsBagInfoMapChannel);
        clientGoodsBagInfoList = getNeedToNotifyClientGoods();
        notifyPlayerCommonData();

    }

    private static  Map<Integer, GoodsInfo> mergeGood(Map<Integer, GoodsInfo> oldMap , Map<Integer, GoodsInfo> channelMap){
        for(GoodsInfo channelGoodsInfo : channelMap.values()){
            oldMap.put(channelGoodsInfo.getGoodsId(),channelGoodsInfo);
        }
        return oldMap;
    }

    private static  Map<Integer, Map<Integer, List<GoodsBagInfo>>> mergeGoodBag(Map<Integer, Map<Integer, List<GoodsBagInfo>>> oldMap , Map<Integer, Map<Integer, List<GoodsBagInfo>>> channelMap){
        for(Integer key : channelMap.keySet()){
            Map<Integer, List<GoodsBagInfo>> temp = channelMap.get(key);
            oldMap.put(key,temp);
        }
        return oldMap;
    }

    /**
     * 获取需要同步给客户端的概率信息
     * @return
     */
    public static List<GoodsBagInfo> getNeedToNotifyClientGoods() {
        List<GoodsBagInfo> bagInfoList = new ArrayList<>();
        for (GoodsInfo goodsInfo : goodsInfoMap.values()) {
            if (goodsInfo.getType() == eGoodsType.OptionalBox.getValue()
                    || goodsInfo.getType() == eGoodsType.OptionalBoxEx.getValue()
                    || goodsInfo.getType() == eGoodsType.SpecialBox.getValue()
                    || goodsInfo.getType() == eGoodsType.TravelBookOptionalPack.getValue()
                    || goodsInfo.getType() == eGoodsType.TravelBookRandomPack.getValue()) {
                Map<Integer, List<GoodsBagInfo>> map = CommonMgr.getGoodsBagInfoMap().get(goodsInfo.getGoodsId());
                if (map != null) {
                    for (List<GoodsBagInfo> list : map.values()) {
                        bagInfoList.addAll(list);
                    }
                }
            }
            if (ChannelConfig.SHOW_GOOD_BAG_RATE == 1) {
                // 如果展示
                if (goodsInfo.getType() == eGoodsType.GoodsBag.getValue() || goodsInfo.getType() == eGoodsType.CommonActivityGood.getValue()) {
                    Map<Integer, List<GoodsBagInfo>> map = CommonMgr.getGoodsBagInfoMap().get(goodsInfo.getGoodsId());
                    if (map != null) {
                        for (List<GoodsBagInfo> list : map.values()) {
                            bagInfoList.addAll(list);
                        }
                    }
                }
            }
            //五熊争霸的残卷道具要发下去，客户端要显示
            FiveHeroConfig fiveHeroConfig = FiveHeroMgr.getConfig();
            if(fiveHeroConfig != null && goodsInfo.getGoodsId() == fiveHeroConfig.getBookItemId()){
                Map<Integer, List<GoodsBagInfo>> map = CommonMgr.getGoodsBagInfoMap().get(goodsInfo.getGoodsId());
                if (map != null) {
                    for (List<GoodsBagInfo> list : map.values()) {
                        bagInfoList.addAll(list);
                    }
                }
            }
        }
        return bagInfoList;
    }


    private static void notifyPlayerCommonData(){
        List<GamePlayer> playerList = GamePlayerMgr.getCopyPlayerList();
        for(GamePlayer player : playerList){
            player.getModule(CommonModule.class).syncCommonData();
        }
    }

    /**
     * 获取礼包里面随机道具信息列表
     */
    public static List<GoodsBagInfo> getRandomGoodsList(int bagId) {
        List<GoodsBagInfo> resultGoodsList = new ArrayList<>();
        Map<Integer, List<GoodsBagInfo>> goodsMap = goodsBagInfoMap.get(bagId);
        if(null == goodsMap) {
            return null;
        }
        for(List<GoodsBagInfo> goodsList : goodsMap.values()){
            int sumWeight = 0;
            for(GoodsBagInfo goodsBagInfo : goodsList){
                sumWeight += goodsBagInfo.getRandomWeight();
            }
            if(sumWeight > 0){
                int randomWeight = threadSafeRandom.next(0, sumWeight);
                int tempWeight = 0;
                for(GoodsBagInfo goodsBagInfo : goodsList){
                    tempWeight += goodsBagInfo.getRandomWeight();
                    if(tempWeight > randomWeight){
                        resultGoodsList.add(goodsBagInfo);
                        break;
                    }
                }
            }
        }
        return resultGoodsList;
    }

    public static List<GoodsBagInfo> getBoxAllBagInfoList(int boxId){
        List<GoodsBagInfo> goodsBagInfoList = new ArrayList<>();
        Map<Integer, List<GoodsBagInfo>> map = goodsBagInfoMap.get(boxId);
        if(map != null){
            for(List<GoodsBagInfo> list : map.values()){
                goodsBagInfoList.addAll(list);
            }
        }
        return goodsBagInfoList;
    }

    public static GoodsInfo getGoodsInfo(int goodsId){
        return goodsInfoMap.get(goodsId);
    }

    public static List<GoodsInfo> getGoodsInfoList(){
        return new ArrayList<>(goodsInfoMap.values());
    }

    public static Map<Integer, Map<Integer, List<GoodsBagInfo>>> getGoodsBagInfoMap() {
        return goodsBagInfoMap;
    }

    public static List<GoodsBagInfo> getClientGoodsBagInfoList() {
        return clientGoodsBagInfoList;
    }

    public static void setClientGoodsBagInfoList(List<GoodsBagInfo> clientGoodsBagInfoList) {
        CommonMgr.clientGoodsBagInfoList = clientGoodsBagInfoList;
    }

    public static List<GoodsBagInfo> getGoodsBagInfoList(int bagId){
        List<GoodsBagInfo> goodsBagInfoList = new ArrayList<>();
        Map<Integer, List<GoodsBagInfo>> map = goodsBagInfoMap.get(bagId);
        if(map != null){
            for (List<GoodsBagInfo> infoList : map.values()) {
                goodsBagInfoList.addAll(infoList);
            }
        }
        return goodsBagInfoList;
    }


    public static long getTargetServerIdByUserId(long targetUserId){
        long targetServerId = RelativesMgr.getUserServerId(targetUserId);

        CrossUnionMember unionMember = CrossUnionMgr.getUnionMember(targetUserId);
        if (unionMember != null) {
            targetServerId = unionMember.getServerId();
        } else {
            UserInfo userInfo = UserMgr.getUserInfo(targetUserId);
            if (userInfo != null) {
                targetServerId = userInfo.getOriginalServerId();
            }
        }
        return targetServerId;
    }

    /**
     * 获取礼包里面随机道具，剔除部分无须随机的道具
     *
     * @param bagId  盒子ID
     * @param player 玩家
     * @param hasGet 已经获得的道具
     * @return List<GoodsBagInfo>
     */
    public static List<GoodsBagInfo> getRandomGoodsList(int bagId, GamePlayer player, Property hasGet) {
        List<GoodsBagInfo> resultGoodsList = new ArrayList<>();
        Map<Integer, List<GoodsBagInfo>> goodsMap = goodsBagInfoMap.get(bagId);
        if (null == goodsMap) {
            return null;
        }
        for (List<GoodsBagInfo> goodsList : goodsMap.values()) {
            int sumWeight = 0;
            Set<Integer> invalidGoods = new HashSet<>(); // 不用参与随机的道具
            for (GoodsBagInfo goodsBagInfo : goodsList) {
                int goodsId = goodsBagInfo.getGoodsId();
                if (GoodsMgr.isTravelCard(goodsId) && player.getModule(TravelBookModule.class).checkCardGetMaxLevel(goodsId, hasGet)) {
                    invalidGoods.add(goodsId);
                    continue;
                }
                sumWeight += goodsBagInfo.getRandomWeight();
            }
            if (sumWeight > 0) {
                int randomWeight = threadSafeRandom.next(0, sumWeight);
                int tempWeight = 0;
                for (GoodsBagInfo goodsBagInfo : goodsList) {
                    if (invalidGoods.contains(goodsBagInfo.getGoodsId())) {
                        continue;
                    }
                    tempWeight += goodsBagInfo.getRandomWeight();
                    if (tempWeight > randomWeight) {
                        resultGoodsList.add(goodsBagInfo);
                        break;
                    }
                }
            }
        }
        return resultGoodsList;
    }
}
